﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Puzzle
{
    [Serializable]
    public partial class Board
    {
        public uint tileMatchingNeighbor(int index)
        {
            uint count = 0;
            if (this.tiles[index].top == this.tiles[index - 10].bottom)
                count++;
            if (this.tiles[index].bottom == this.tiles[index + 10].top)
                count++;
            if (this.tiles[index].left == this.tiles[index - 1].right)
                count++;
            if (this.tiles[index].right == this.tiles[index + 1].left)
                count++;

            return count;                    
        }
        public enum sides { left, right, down, up };
        public List<Tile> tiles;
        public Board(List<string> input)
        {
            this.tiles = new List<Tile>(input.Count / 4);
            Tile tempTile = null;
            for (int i = 0; i < input.Count; i++)
            {
                switch (i % 4)
                {
                    case 0:
                        int t = int.Parse(input[i]);
                        tempTile = new Tile();
                        tempTile.top = int.Parse(input[i]);
                        break;
                    case 1:
                        tempTile.right = int.Parse(input[i]);
                        break;
                    case 2:
                        tempTile.bottom = int.Parse(input[i]);
                        break;
                    case 3:
                        tempTile.left = int.Parse(input[i]);
                        this.tiles.Add(tempTile);
                        break;
                    default:
                        break;
                }

            }
        }
        public Board() { return; }
        public void outputBoard(string destination)
        {
            string temp = "";
            File.WriteAllText(destination, ""); //overwrite new file
            foreach (Tile t in this.tiles)
            {
                temp += "   ";
                temp += t.top.ToString();
                temp += " ";
                temp += t.right.ToString();
                temp += " ";
                temp += t.bottom.ToString();
                temp += " ";
                temp += t.left.ToString();
                temp += " ";
            }
            File.AppendAllText(destination, temp);
        }
        public void rotateEdgePieceCorrectly(int index)
        {
            if (!(this.tiles[index].isEdgePiece()))
                throw new CustomExc("in rotateEdgePieceCorrectly, the piece itself is not a piece that would go on the edge");

            switch (whichEdge(index))
            {
                case edgePlacement.down:
                    while (this.tiles[index].bottom != 0)
                        rotatePiece(index, 1);
                    break;
                case edgePlacement.up:
                    while (this.tiles[index].top != 0)
                        rotatePiece(index, 1);
                    break;
                case edgePlacement.left:
                    while (this.tiles[index].left != 0)
                        rotatePiece(index, 1);
                    break;
                case edgePlacement.right:
                    while (this.tiles[index].right != 0)
                        rotatePiece(index, 1);
                    break;
                default:
                    throw new CustomExc("in rotateEdgePieceCorrectly, the passed index does not refer to a piece on the edge");
            }


        }
        public void rotateCornerPieceCorrectly(int index)
        {
            if (!(this.tiles[index].isCornerPiece()))
                throw new CustomExc("in rotateCornerPieceCorrectly, the piece itself is not a piece that would go on in a corner");

            switch (whichEdge(index))
            {
                case edgePlacement.down_left:
                    while (this.tiles[index].bottom != 0 && this.tiles[index].left != 0)
                        rotatePiece(index, 1);
                    break;
                case edgePlacement.down_right:
                    while (this.tiles[index].bottom != 0 && this.tiles[index].right != 0)
                        rotatePiece(index, 1);
                    break;
                case edgePlacement.up_right:
                    while (this.tiles[index].top != 0 && this.tiles[index].right != 0)
                        rotatePiece(index, 1);
                    break;
                case edgePlacement.up_left:
                    while (this.tiles[index].top != 0 && this.tiles[index].left != 0)
                        rotatePiece(index, 1);
                    break;
                default:
                    throw new CustomExc("in rotateCornerPieceCorrectly, the passed index does not refer to a piece that's in a corner");
            }
        }

        public long getIndexPieceOnEdge()
        {
            int[] edges = new int[32] { 1, 2, 3, 4, 5, 6, 7, 8, 10, 20, 30, 40, 50, 60, 70, 80, 19, 29, 39, 49, 59, 69, 79, 89, 91, 92, 93, 94, 95, 96, 97, 98 };
            Random ran = new Random();

            return (long)(edges[ran.Next(0,32)]);
        }
        
        public long getIndexPieceOnCorner()
        {
            int[] edges = new int[4] { 0, 9, 90, 99 };
            Random ran = new Random();
            return (long)(edges[ran.Next(0, 4)]);
        }

        public long getIndexPieceInMiddle()
        {
            Random ran = new Random();
            long ret;
            do
            {
                ret = ran.Next(0, 100);

            }
            while (whichEdge((int)ret) != edgePlacement.none);
            return ret;
        }

        public bool canBeUsedInBlockSlide(int index)
        {
            if (onCorner(index) == true)
                return false;
            if (onEdge(index) == true)
                return false;
            return true;
        }

        public bool matchesOnSide(sides s, int index)
        {
            switch (s)
            {
                case sides.down:



                    break;
                case sides.left:

                    break;
                case sides.right:

                    break;
                case sides.up:

                    break;

                default:
                    throw new CustomExc("in matchesOnSide, default case was hit");
            }
            throw new CustomExc("in matchesOnSide, switch statement should never had exited");
            return false;

        }

    }
}
